"""
配置管理器
"""

import os
import yaml
import json
from pathlib import Path
from typing import Dict, Any, Optional, Union
from dataclasses import dataclass

from ..core.logger import app_logger


@dataclass
class DatabaseConfig:
    """数据库配置"""
    url: str
    echo: bool = False
    pool_size: int = 10
    max_overflow: int = 20


@dataclass  
class RedisConfig:
    """Redis配置"""
    url: str
    decode_responses: bool = True
    socket_timeout: int = 5


@dataclass
class AIConfig:
    """AI配置"""
    provider: str = "openai"
    openai_model: str = "gpt-3.5-turbo"
    openai_max_tokens: int = 300
    openai_temperature: float = 0.7
    openai_timeout: int = 30
    claude_model: str = "claude-3-sonnet-20240229"
    claude_max_tokens: int = 300
    claude_timeout: int = 30


@dataclass
class PlatformConfig:
    """平台配置"""
    enabled: bool = True
    max_length: int = 280
    rate_limit: int = 15


@dataclass
class ScrapingConfig:
    """抓取配置"""
    interval: int = 1800
    retry_times: int = 3
    retry_delay: int = 60
    max_items: int = 50
    timeout: int = 30


@dataclass
class SchedulerConfig:
    """调度器配置"""
    enabled: bool = True
    timezone: str = "Asia/Shanghai"
    max_workers: int = 4


class ConfigManager:
    """配置管理器"""
    
    def __init__(self, config_path: str = "config/config.yaml"):
        self.config_path = Path(config_path)
        self.config_data: Dict[str, Any] = {}
        self.load_config()
    
    def load_config(self):
        """加载配置文件"""
        try:
            if self.config_path.exists():
                with open(self.config_path, 'r', encoding='utf-8') as f:
                    self.config_data = yaml.safe_load(f) or {}
                app_logger.info(f"配置文件加载成功: {self.config_path}")
            else:
                app_logger.warning(f"配置文件不存在: {self.config_path}，使用默认配置")
                self.config_data = self._get_default_config()
        except Exception as e:
            app_logger.error(f"加载配置文件失败: {e}")
            self.config_data = self._get_default_config()
    
    def save_config(self):
        """保存配置文件"""
        try:
            # 确保配置目录存在
            self.config_path.parent.mkdir(parents=True, exist_ok=True)
            
            with open(self.config_path, 'w', encoding='utf-8') as f:
                yaml.dump(
                    self.config_data, 
                    f, 
                    default_flow_style=False, 
                    allow_unicode=True,
                    indent=2
                )
            app_logger.info(f"配置文件保存成功: {self.config_path}")
            return True
        except Exception as e:
            app_logger.error(f"保存配置文件失败: {e}")
            return False
    
    def get(self, key: str, default: Any = None) -> Any:
        """获取配置值（支持点号分隔的嵌套键）"""
        keys = key.split('.')
        value = self.config_data
        
        try:
            for k in keys:
                value = value[k]
            return value
        except (KeyError, TypeError):
            return default
    
    def set(self, key: str, value: Any) -> bool:
        """设置配置值（支持点号分隔的嵌套键）"""
        keys = key.split('.')
        config = self.config_data
        
        try:
            # 创建嵌套字典结构
            for k in keys[:-1]:
                if k not in config:
                    config[k] = {}
                config = config[k]
            
            config[keys[-1]] = value
            return True
        except Exception as e:
            app_logger.error(f"设置配置值失败: {e}")
            return False
    
    def update(self, updates: Dict[str, Any]) -> bool:
        """批量更新配置"""
        try:
            for key, value in updates.items():
                self.set(key, value)
            return True
        except Exception as e:
            app_logger.error(f"批量更新配置失败: {e}")
            return False
    
    def get_database_config(self) -> DatabaseConfig:
        """获取数据库配置"""
        db_config = self.get('database', {})
        return DatabaseConfig(
            url=db_config.get('url', 'sqlite:///./auto_post.db'),
            echo=db_config.get('echo', False),
            pool_size=db_config.get('pool_size', 10),
            max_overflow=db_config.get('max_overflow', 20)
        )
    
    def get_redis_config(self) -> RedisConfig:
        """获取Redis配置"""
        redis_config = self.get('redis', {})
        return RedisConfig(
            url=redis_config.get('url', 'redis://localhost:6379/0'),
            decode_responses=redis_config.get('decode_responses', True),
            socket_timeout=redis_config.get('socket_timeout', 5)
        )
    
    def get_ai_config(self) -> AIConfig:
        """获取AI配置"""
        ai_config = self.get('ai', {})
        openai_config = ai_config.get('openai', {})
        claude_config = ai_config.get('claude', {})
        
        return AIConfig(
            provider=ai_config.get('provider', 'openai'),
            openai_model=openai_config.get('model', 'gpt-3.5-turbo'),
            openai_max_tokens=openai_config.get('max_tokens', 300),
            openai_temperature=openai_config.get('temperature', 0.7),
            openai_timeout=openai_config.get('timeout', 30),
            claude_model=claude_config.get('model', 'claude-3-sonnet-20240229'),
            claude_max_tokens=claude_config.get('max_tokens', 300),
            claude_timeout=claude_config.get('timeout', 30)
        )
    
    def get_platform_config(self, platform: str) -> PlatformConfig:
        """获取指定平台配置"""
        platforms_config = self.get('platforms', {})
        platform_config = platforms_config.get(platform, {})
        
        # 默认配置
        defaults = {
            'weibo': {'max_length': 140, 'rate_limit': 10},
            'twitter': {'max_length': 280, 'rate_limit': 15},
            'wechat': {'max_length': 2000, 'rate_limit': 4}
        }
        
        default = defaults.get(platform, {'max_length': 280, 'rate_limit': 15})
        
        return PlatformConfig(
            enabled=platform_config.get('enabled', True),
            max_length=platform_config.get('max_length', default['max_length']),
            rate_limit=platform_config.get('rate_limit', default['rate_limit'])
        )
    
    def get_scraping_config(self) -> ScrapingConfig:
        """获取抓取配置"""
        scraping_config = self.get('scraping', {})
        return ScrapingConfig(
            interval=scraping_config.get('interval', 1800),
            retry_times=scraping_config.get('retry_times', 3),
            retry_delay=scraping_config.get('retry_delay', 60),
            max_items=scraping_config.get('max_items', 50),
            timeout=scraping_config.get('timeout', 30)
        )
    
    def get_scheduler_config(self) -> SchedulerConfig:
        """获取调度器配置"""
        scheduler_config = self.get('scheduler', {})
        return SchedulerConfig(
            enabled=scheduler_config.get('enabled', True),
            timezone=scheduler_config.get('timezone', 'Asia/Shanghai'),
            max_workers=scheduler_config.get('max_workers', 4)
        )
    
    def is_mock_mode(self) -> bool:
        """检查是否为模拟模式"""
        return self.get('development.mock_mode', True)
    
    def is_debug_mode(self) -> bool:
        """检查是否为调试模式"""
        return self.get('app.debug', True)
    
    def get_content_styles(self) -> list:
        """获取可用的内容风格"""
        return self.get('content.styles', ['default', 'formal', 'casual', 'humorous'])
    
    def get_sensitive_words_file(self) -> str:
        """获取敏感词文件路径"""
        return self.get('security.sensitive_words_file', './config/sensitive_words.txt')
    
    def get_data_retention_days(self, data_type: str) -> int:
        """获取数据保留天数"""
        retention_config = self.get('data_retention', {})
        defaults = {
            'trends': 30,
            'contents': 90,
            'logs': 7,
            'publish_records': 180
        }
        return retention_config.get(f'{data_type}_days', defaults.get(data_type, 30))
    
    def export_config(self, format: str = 'yaml') -> str:
        """导出配置"""
        try:
            if format.lower() == 'json':
                return json.dumps(self.config_data, indent=2, ensure_ascii=False)
            else:
                return yaml.dump(self.config_data, default_flow_style=False, allow_unicode=True)
        except Exception as e:
            app_logger.error(f"导出配置失败: {e}")
            return ""
    
    def import_config(self, config_str: str, format: str = 'yaml') -> bool:
        """导入配置"""
        try:
            if format.lower() == 'json':
                new_config = json.loads(config_str)
            else:
                new_config = yaml.safe_load(config_str)
            
            if isinstance(new_config, dict):
                self.config_data = new_config
                app_logger.info("配置导入成功")
                return True
            else:
                app_logger.error("导入的配置格式无效")
                return False
        except Exception as e:
            app_logger.error(f"导入配置失败: {e}")
            return False
    
    def _get_default_config(self) -> Dict[str, Any]:
        """获取默认配置"""
        return {
            'app': {
                'name': '自动文章发送工具',
                'version': '1.0.0',
                'debug': True,
                'log_level': 'INFO'
            },
            'database': {
                'url': 'sqlite:///./auto_post.db',
                'echo': False
            },
            'redis': {
                'url': 'redis://localhost:6379/0'
            },
            'ai': {
                'provider': 'openai',
                'openai': {
                    'model': 'gpt-3.5-turbo',
                    'max_tokens': 300,
                    'temperature': 0.7
                }
            },
            'platforms': {
                'weibo': {'enabled': True, 'max_length': 140},
                'twitter': {'enabled': True, 'max_length': 280},
                'wechat': {'enabled': True, 'max_length': 2000}
            },
            'scraping': {
                'interval': 1800,
                'retry_times': 3
            },
            'scheduler': {
                'enabled': True,
                'timezone': 'Asia/Shanghai'
            },
            'development': {
                'mock_mode': True
            }
        }


# 全局配置管理器实例
config_manager = ConfigManager()